package org.yuanqiframework.yuanqi.boot.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.yuanqiframework.yuanqi.boot.sys.entity.SysRole;
import org.yuanqiframework.yuanqi.boot.sys.entity.SysUserRole;
import org.yuanqiframework.yuanqi.boot.sys.mapper.SysRoleMapper;
import org.yuanqiframework.yuanqi.boot.sys.mapper.SysUserRoleMapper;
import org.yuanqiframework.yuanqi.boot.sys.service.SysUserRoleService;
import org.yuanqiframework.yuanqi.boot.sys.utils.BusinessExceptionUtils;
import org.yuanqiframework.yuanqi.web.auth.service.LoginService;
import org.yuanqiframework.yuanqi.core.utils.StringUtils;
import org.yuanqiframework.yuanqi.web.exception.BusinessException;
import org.yuanqiframework.yuanqi.core.utils.BeanUtils;
import org.yuanqiframework.yuanqi.boot.sys.dto.LoginUserDTO;
import org.yuanqiframework.yuanqi.boot.sys.dto.SysUserDTO;
import org.yuanqiframework.yuanqi.boot.sys.dto.SysUserQueryDTO;
import org.yuanqiframework.yuanqi.boot.sys.entity.SysUser;
import org.yuanqiframework.yuanqi.boot.sys.mapper.SysUserMapper;
import org.yuanqiframework.yuanqi.boot.sys.service.ImageCaptchaService;
import org.yuanqiframework.yuanqi.boot.sys.service.SysDeptService;
import org.yuanqiframework.yuanqi.boot.sys.service.SysUserService;
import org.yuanqiframework.yuanqi.boot.sys.utils.SysRsaUtils;
import org.yuanqiframework.yuanqi.boot.sys.vo.SysUserVO;
import org.yuanqiframework.yuanqi.boot.sys.vo.UserInfoVO;
import org.springframework.stereotype.Service;
import org.yuanqiframework.yuanqi.web.utils.env.EnvUtils;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author cbt28
 * @description 针对表【sys_user】的数据库操作Service实现
 * @createDate 2025-05-30 22:33:03
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser>
        implements SysUserService {

    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private SysDeptService sysDeptService;
    @Resource
    private ImageCaptchaService imageCaptchaService;
    @Resource
    private LoginService loginService;
    @Resource
    private SysUserRoleService sysUserRoleService;
    @Resource
    private SysRoleMapper sysRoleMapper;
    @Resource
    private SysUserRoleMapper sysUserRoleMapper;


    @Override
    public Page<SysUserVO> listUser(SysUserQueryDTO sysUserQueryDTO) {
        if (sysUserQueryDTO.getDeptId() != null && !"".equals(sysUserQueryDTO.getDeptId())) {
            List<String> deptIds = sysDeptService.getChildDeptIds(sysUserQueryDTO.getDeptId());
            sysUserQueryDTO.setDeptIds(deptIds);
        }
        Page<SysUserVO> page = new Page<>(sysUserQueryDTO.getPageNum(), sysUserQueryDTO.getPageSize());
        IPage<SysUserVO> result = sysUserMapper.listUser(page, sysUserQueryDTO);
        return (Page<SysUserVO>) result;
    }

    @Override
    public String getPasswordByUsername(String username) {
        List<String> psw = sysUserMapper.selectObjs(new LambdaQueryWrapper<SysUser>()
                .select(SysUser::getPassword)
                .eq(SysUser::getUsername, username));
        if (psw == null || psw.size() == 0) {
            return null;
        }
        return psw.get(0);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveUser(SysUserDTO sysUserDTO) {
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(sysUserDTO, sysUser);
        sysUser.setId(StringUtils.getUUID());
        sysUser.setPassword(sysUserDTO.getUsername());
        sysUser.setCreatedAt(new Date());
        //检测username唯一
        if (sysUserMapper.selectCount(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUsername, sysUserDTO.getUsername())) > 0) {
            throw new BusinessException("用户名[" + sysUserDTO.getUsername() + "]已存在");
        }
        int insert = sysUserMapper.insert(sysUser);
        if (insert > 0) {
            List<SysRole> roleList = sysRoleMapper.selectList(null);
            String id = sysUser.getId();
            List<SysUserRole> sysUserRoles = new ArrayList<>();
            for (String role : sysUserDTO.getRoles()) {
                SysUserRole sysUserRole = new SysUserRole();
                sysUserRole.setId(StringUtils.getUUID());
                sysUserRole.setUserId(id);
                sysUserRole.setRoleId(roleList.stream().filter(sysRole -> sysRole.getRoleCode().equals(role)).findFirst().orElse(new SysRole()).getId());
                sysUserRoles.add(sysUserRole);
            }
            if (!sysUserRoles.isEmpty()) {
                sysUserRoleService.saveBatch(sysUserRoles);
            }
        }
        return insert > 0;
    }

    @Override
    public boolean updateUser(String id, SysUserDTO sysUserDTO) {
        SysUser sysUser = new SysUser();
        sysUser.setId(id);
        BeanUtils.copyProperties(sysUserDTO, sysUser);
        sysUser.setUsername(null);
        sysUser.setUpdatedAt(new Date());
        int i = sysUserMapper.updateById(sysUser);
        if (i > 0) {
            sysUserRoleService.remove(new LambdaQueryWrapper<SysUserRole>()
                    .eq(SysUserRole::getUserId, id));
            List<SysRole> roleList = sysRoleMapper.selectList(null);
            List<SysUserRole> sysUserRoles = new ArrayList<>();
            for (String role : sysUserDTO.getRoles()) {
                SysUserRole sysUserRole = new SysUserRole();
                sysUserRole.setId(StringUtils.getUUID());
                sysUserRole.setUserId(id);
                sysUserRole.setRoleId(roleList.stream().filter(sysRole -> sysRole.getRoleCode().equals(role)).findFirst().orElse(new SysRole()).getId());
                sysUserRoles.add(sysUserRole);
            }
            if (!sysUserRoles.isEmpty()) {
                sysUserRoleService.saveBatch(sysUserRoles);
            }
        }
        return i > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean changePassword(String userId, String oldPassword, String newPassword) {
        if (sysUserMapper.selectCount(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getId, userId)
                .eq(SysUser::getPassword, oldPassword)) == 0) {
            throw new BusinessException("旧密码错误");
        }
        SysUser sysUser = new SysUser();
        sysUser.setId(userId);
        sysUser.setPassword(newPassword);
        return sysUserMapper.updateById(sysUser) > 0;
    }


    @Override
    public UserInfoVO login(LoginUserDTO loginUserDTO) {
        String username = loginUserDTO.getUsername();
        //解密
        String password = SysRsaUtils.decrypt(loginUserDTO.getPassword());
        if (EnvUtils.isDev()) {
            //开发环境，验证码不生效
        } else {
            // 验证验证码是否正确
            BusinessExceptionUtils.throwBusinessException(!imageCaptchaService.
                            check(loginUserDTO.getCaptchaKey(),
                                    loginUserDTO.getCaptchaCode()),
                    "验证码错误");
        }
        //根据用户名和密码查询用户信息

        String dbPassword = getPasswordByUsername(username);
        //验证用户信息是否正确
        BusinessExceptionUtils.throwBusinessException(!loginService.passwordMatch(dbPassword, password), "用户名或密码错误");

        SysUser user = sysUserMapper.selectOne(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUsername, username));
        String status = user.getStatus();
        if (!"0".equals(status)) {
            throw new BusinessException("用户已禁用");
        }
        if ("0".equals(status)) {
            user.setStatus("正常");
        } else if ("1".equals(status)) {
            user.setStatus("禁用");
        } else {
            user.setStatus("未知");
        }

        String sex = user.getSex();
        if ("0".equals(sex)) {
            user.setSex("男");
        } else if ("1".equals(sex)) {
            user.setSex("女");
        } else {
            user.setSex("未知");
        }
        Set<String> roleCodes = sysUserRoleMapper.listRoleCodeByUserId(user.getId());
        UserInfoVO userInfoVO = new UserInfoVO();
        userInfoVO.setUserId(user.getId());
        userInfoVO.setUsername(user.getUsername());
        userInfoVO.setNickname(user.getNickname());
        userInfoVO.setAvatar(user.getAvatar());
        userInfoVO.setPhone(user.getPhone());
        userInfoVO.setEmail(user.getEmail());
        userInfoVO.setSex(user.getSex());
        userInfoVO.setStatus(user.getStatus());
        userInfoVO.setRoles(roleCodes);
        //生成token并返回
        String token = loginService.loginGetToken(user.getId(), userInfoVO.getUsername(), userInfoVO.getRoles());
        userInfoVO.setUserId(user.getId());
        userInfoVO.setToken(token);
        return userInfoVO;
    }
}




